import get from "lodash/get";
import {getContext} from "./toml"
// 字符串表达式执行 并返回结果
const doEval = (s = "", obj:Record<string,any> = {}) => {
  // 剔除不能作为 key 值的 字符串 如 onUpdate:XXX
  const keys = Object.keys(obj).filter(k => s.includes(k));
  const vals = keys.map((k) => get(obj, k));
  const str = "return " + s;
  try {
    return new Function(...keys, str)(...vals);
  } catch (e) {
    console.error(":::::::::: 字符串表达式执行异常！ :::::::::", s, obj);
    console.error(keys, vals, str);
    console.error(e);
  }
  return undefined;
};

// 循环匹配并执行回调
export const loopExec = (reg:RegExp, str:string, call:(r:any) => void) => {
  let t;
  while ((t = reg.exec(str)) !== null) {
    call(t);
  }
};

// 模板内容替换 模板 = {{ \w+ }}
const DEFAULT_TEMP_REG = /\{\{\s*(.*?)\s*\}\}/g;
export const getTempValue = (str:string, ctx:Record<string,any> = getContext(), reg = DEFAULT_TEMP_REG) => {
  if(!str){
    return str;
  }
  let res = str;
  loopExec(reg, str, ([s, k]) => {
    const v = doEval(k, ctx);
    res = res.replace(s, v);
  });
  return res;
};

// 递归遍历对象并进行模板替换
export const replaceObj = (obj:any,ctx:Record<string,any> = {},reg = DEFAULT_TEMP_REG) => {
  if(!obj || typeof obj != 'object'){
    return obj;
  }
  //
  if(Array.isArray(obj)){
    const res:any[] = []
    obj.forEach(v => {
      const tv = typeof v === 'string' ? getTempValue(v,ctx,reg) : replaceObj(v,ctx,reg);
      res.push(tv)
    })
    return res;
  }else{
    const res:Record<string,any> = {}
    Object.keys(obj).forEach(k => {
      const v = obj[k];
      const tk = getTempValue(k,ctx,reg);
      const tv = typeof v === 'string' ? getTempValue(v,ctx,reg) : replaceObj(v,ctx,reg);
      res[tk] = tv;
    })
    return res;
  }
  
}